package com.example.springboot.wechat.wechatinterface.job;

import com.example.springboot.wechat.wechatinterface.util.WeChatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.servlet.ServletContext;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 定时刷新微信token
 */
@Component
public class TokenCache implements CommandLineRunner {

	private static final Log log = LogFactory.getLog(TokenCache.class);

	private static ConcurrentMap<String, String> CACHE = new ConcurrentHashMap<String, String>();

	private ServletContext servletContext;

	// 定时任务启动之后间隔时长开始执行定时任务(单位：秒)
	private final int INITIAL_DELAY = 60;

	// 定时任务的执行周期(单位：毫秒)，每隔2小时执行一次
	@Value("${token_refresh_period}")
	private int PERIOD_TMP = 2 * 60 * 60;

	@Value("${wechat_openid}")
	private String appid;
	@Value("${wechat_appsecret}")
	private String appsecret;

	@Override
	public void run(String... args) throws Exception {
		log.info("token缓存管理-->缓存初始化:服务启动!");
		load();
		refreshCacheData();
		log.info("token缓存管理-->缓存初始化:服务加载结束!");
	}

	/**
	 * @param
	 * @return void
	 * @author cjy
	 * @Description: 定时刷新缓存数据
	 * @date 2017-6-2
	 */
	private void refreshCacheData() {
		ScheduledExecutorService executors = Executors.newSingleThreadScheduledExecutor();
		// 当数据库配置的为空时走默认5分钟
		executors.scheduleAtFixedRate(new CacheDataRefresh(), INITIAL_DELAY, PERIOD_TMP, TimeUnit.SECONDS);
	}


	/**
	 * 加载全局token缓存
	 */
	public void load() {
		try {
			// 加载全局token缓存
			Map<String, String> map = WeChatUtils.getAccessToken(appid, appsecret);
			if (map.containsKey("access_token")) {
				log.info("缓存管理-->刷新缓存:定时调用刷新服务结果：" + map.toString());
				String access_token = map.get("access_token");
				CACHE.put("access_token", access_token);
				// 加载web端token缓存
				this.loadJSAPITicket(access_token);
			}
		} catch (Exception e) {
			log.error("获取全局token或者js-sdk token异常：" + e.getMessage());
		}
	}

	/**
	 * 加载web端token缓存
	 */
	public void loadJSAPITicket(String access_token) throws Exception {
		Map<String, String> map = WeChatUtils.getJSSDKToken(access_token);
		if (map.containsKey("ticket")) {
			log.info("缓存管理-->刷新缓存:定时调用刷新服务结果：" + map.toString());
			String jsapi_ticket = map.get("ticket");
			CACHE.put("jsapi_ticket", jsapi_ticket);
		}
	}


	// 重新加载缓存
	public void reload() {
		CACHE.clear();
		load();
	}

	// 获取缓存
	public ConcurrentMap<String, String> getCache() {
		return CACHE;
	}

	// 获取某个缓存
	public String getCache(String key) {
		String cacheEntity = CACHE.get(key);
		if (cacheEntity == null) {
			//没有缓存，则重新加载一次
			load();
			return CACHE.get(key);
		} else {
			return CACHE.get(key);
		}
	}


	/**
	 * 添加缓存
	 *
	 * @param key
	 * @param value
	 */
	public void setCacheData(String key, String value) {
		String cacheEntity = CACHE.get(key);
		if (null != cacheEntity) {
			// 更新缓存中的map数据
			CACHE.put(key, value);
		}
	}

	// 缓存中删除数据
	public void remove(String key, String value) {
		CACHE.remove(key);
	}

	// 销毁缓存
	public void destory() {
		CACHE.clear();
	}

	/**
	 * 刷新缓存定时处理类
	 */
	class CacheDataRefresh implements Runnable {
		@Override
		public void run() {
			try {
				load();
			} catch (Exception e) {
				e.printStackTrace();
				log.error("缓存管理-->刷新缓存:定时调用刷新服务出现异常", e);
			}
		}
	}

}
